package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.common.ErrorCode;
import com.example.demo.enums.UserRoleEnum;
import com.example.demo.exception.BusinessException;
import com.example.demo.exception.ThrowUtils;
import com.example.demo.model.dto.user.UserQueryRequest;
import com.example.demo.model.entity.User;
import com.example.demo.model.vo.LoginUserVO;
import com.example.demo.model.vo.UserVO;
import com.example.demo.service.UserService;
import com.example.demo.mapper.UserMapper;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.example.demo.constant.UserConstant.USER_LOGIN_STATE;

/**
* @author 27658
* @description 针对表【user(用户)】的数据库操作Service实现
* @createDate 2025-04-22 09:35:31
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    private static final String SALT = "bJIan_key";

    @Override
    public User getLoginUser(HttpServletRequest request) {
        // 先判断是否已登录
        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        User currentUser = (User) userObj;
        if (currentUser == null || currentUser.getId() == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        // 从数据库查询（追求性能的话可以注释，直接走缓存）
        long userId = currentUser.getId();
        currentUser = this.getById(userId);
        if (currentUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        return currentUser;
    }

    @Override
    public long userRegister(String userAccount, String userPassword, String checkPassword) {
        // 校验非空
        ThrowUtils.throwIf(userAccount == null || userAccount.length() < 4,
                ErrorCode.PARAMS_ERROR,"用户账号格式错误");
        ThrowUtils.throwIf(userPassword == null || userPassword.length() < 8,
                ErrorCode.PARAMS_ERROR,"用户密码格式错误");
        ThrowUtils.throwIf(checkPassword == null || checkPassword.length() < 8,
                ErrorCode.PARAMS_ERROR,"确认密码格式错误");
        ThrowUtils.throwIf(!userPassword.equals(checkPassword),ErrorCode.PARAMS_ERROR,"两次密码不一致");
        // 校验账号是否已存在
        synchronized (userAccount.intern()) {
            // 账户不能重复
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("userAccount", userAccount);
            long count = this.baseMapper.selectCount(queryWrapper);
            ThrowUtils.throwIf(count>0, ErrorCode.PARAMS_ERROR,"用户账号已存在");
            // 2. 加密
            String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
            // 3. 插入数据
            User user = new User();
            user.setUserAccount(userAccount);
            user.setUserPassword(encryptPassword);
            //生成随机用户名
            String userName = "用户" + UUID.randomUUID().toString().replace("-", "").substring(0, 8);
            user.setUserName(userName);
            boolean saveResult = this.save(user);
            if (!saveResult) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败，数据库错误");
            }
            return user.getId();
        }
    }

    @Override
    public LoginUserVO getLoginUserVO(User user) {
        if (user == null) {
            return null;
        }
        LoginUserVO loginUserVO = new LoginUserVO();
        BeanUtils.copyProperties(user, loginUserVO);
        return loginUserVO;
    }

    @Override
    public Wrapper<User> getQueryWrapper(UserQueryRequest userQueryRequest) {
        return null;
    }

    @Override
    public LoginUserVO userLogin(String userAccount, String userPassword, HttpServletRequest request) {
        // 校验非空
        ThrowUtils.throwIf(userAccount == null || userAccount.length() < 4,
                ErrorCode.PARAMS_ERROR,"用户账号格式错误");
        ThrowUtils.throwIf(userPassword == null || userPassword.length() < 8,
                ErrorCode.PARAMS_ERROR,"用户密码格式错误");
        // 校验账号是否已存在
        // 2. 加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userAccount", userAccount);
        queryWrapper.eq("userPassword",encryptPassword);
        User user = this.baseMapper.selectOne(queryWrapper);
        ThrowUtils.throwIf(user == null, ErrorCode.PARAMS_ERROR,"用户账号或密码错误");
        // 被封号，禁止登录
        if (user != null && UserRoleEnum.BAN.getValue().equals(user.getUserRole())) {
            throw new BusinessException(ErrorCode.FORBIDDEN_ERROR, "该用户已被封，禁止登录");
        }
        // 3. 记录用户的登录态
        request.getSession().setAttribute(USER_LOGIN_STATE, user);
        return this.getLoginUserVO(user);
    }

    @Override
    public boolean userLogout(HttpServletRequest request) {
        ThrowUtils.throwIf(request.getSession().getAttribute(USER_LOGIN_STATE) == null,
                ErrorCode.NOT_LOGIN_ERROR,"用户未登录");
        request.getSession().removeAttribute(USER_LOGIN_STATE);
        return true;
    }

    @Override
    public UserVO getUserVO(User user) {
        if (user == null) {
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public List<UserVO> getUserVO(List<User> userList) {
        ThrowUtils.throwIf(userList==null, ErrorCode.PARAMS_ERROR,"用户列表不能为空");
        return userList.stream().map(this::getUserVO).collect(Collectors.toList());
    }

    @Override
    public boolean isAdmin(HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(USER_LOGIN_STATE);
        return UserRoleEnum.ADMIN.getValue().equals(user.getUserRole());
    }
}




